#include "common.h"
#include "videodevice.h"

volatile bool isSavePic(false);
volatile bool isSaveVideo(false);
QSemaphore semPic(0);
QSemaphore semVideo(0);

VideoDevice::VideoDevice(QCameraViewfinder * viewFinder, QObject * )
{
    this->m_viewFinder = viewFinder;

    videoTime = new QTimer();
    connect(videoTime, &QTimer::timeout, this, &VideoDevice::onTimerout);
    videoTime->start(999);
    yuv_buffer = (unsigned char *)malloc(VIDEO_WIDTH*VIDEO_HEIGHT*2);

    setCamera(QCameraInfo::defaultCamera());
    openCamera();
}

VideoDevice::~VideoDevice()
{
    delete yuv_buffer;
    delete m_viewFinder;
    delete videoTime;
    delete m_videoProbe;
    delete m_camera;
}

void VideoDevice::setCamera(const QCameraInfo &cameraInfo)
{
    //初始化摄像头
    m_camera = new QCamera(cameraInfo);
    connect(m_camera, &QCamera::stateChanged, this, &VideoDevice::updateCameraState);
    connect(m_camera, QOverload<QCamera::Error>::of(&QCamera::error), this, &VideoDevice::displayCameraError);

    updateCameraState(m_camera->state());

    QCameraViewfinderSettings settings;
    //QVideoFrame::Format_YUYV   QVideoFrame::Format_YUV420P
    settings.setPixelFormat(QVideoFrame::Format_YUYV); //设置像素格式,Android上只支持NV21格式
    settings.setMinimumFrameRate(0);
    settings.setMaximumFrameRate(0);
    settings.setResolution(QSize(VIDEO_WIDTH, VIDEO_HEIGHT)); //设置摄像头的分辨率
    m_camera->setViewfinderSettings(settings);

    m_camera->setViewfinder(m_viewFinder);
    m_viewFinder->move(320, 0);
    m_viewFinder->show();

    m_videoProbe = new QVideoProbe();
    m_videoProbe->setSource(m_camera);
    connect(m_videoProbe, &QVideoProbe::videoFrameProbed, this, &VideoDevice::onProbeFrameSlot);
}

void VideoDevice::openCamera()
{
    m_camera->stop();
    m_camera->unload();
    m_camera->setCaptureMode(QCamera::CaptureVideo);
    m_camera->start();
}
void VideoDevice::updateCameraState(QCamera::State state)
{
    switch (state)
    {
    case QCamera::ActiveState: break;
    case QCamera::UnloadedState:
    case QCamera::LoadedState: break;
    }
}
void VideoDevice::displayCameraError(void)
{
    qDebug()<<"Camera error:"<<m_camera->errorString();
}

void VideoDevice::onProbeFrameSlot(const QVideoFrame &frame)
{
    QVideoFrame cloneFrame(frame);

    if (!cloneFrame.map(QAbstractVideoBuffer::ReadOnly)) {
        return ;
    }

    lock.lock();
    yuv_buffer_len = cloneFrame.mappedBytes();
    if (yuv_buffer_len > VIDEO_WIDTH*VIDEO_HEIGHT*2) {
        yuv_buffer_len = VIDEO_WIDTH*VIDEO_HEIGHT*2;
    }
    memcpy(yuv_buffer, cloneFrame.bits(), yuv_buffer_len);
    lock.unlock();

    //qDebug()<<"mappedBytes="<<cloneFrame.mappedBytes()<<"planeCount="<<   cloneFrame.planeCount()<<"bytesPerLine="<<cloneFrame.bytesPerLine();

    cloneFrame.unmap();

    if(isSavePic){
        semPic.release();
    }
    if(isSaveVideo) {
        semVideo.release();
    }

    timeCnt++;
}

void VideoDevice::onTimerout()
{
    qDebug()<<"time="<<timeCnt;
    timeCnt = 0;
}
